
#include "SoundNodes.h"


class OgreApplication;
class OgreInitializeSettings;





class SoundHandler{

	//ear position
	
	Ogre::Vector3		previousListenerPosition;
	Ogre::Camera*		listener_cam;
	Ogre::SceneNode*	listener_node;
	
	Ogre::Vector3		getListenerPosition();
	Ogre::Quaternion	getListenerOrientation();

	Ogre::Vector3		getListenerVelocity(unsigned long millis);
	bool				getListenerOverSS(Ogre::Vector3 velocityVec);

	//FMOD
	
		FMOD::System*					fmod_system;
		FMOD::Reverb*					reverb;

		//instance array
		SoundInstance**					channel_array;
		int								channel_count;

		void							initializeChannels();	
		void							destroyChannels();
		int								getNextFreeChannel();
		void							removeIndex(int index);
		void							set(int index,SoundInstance* inst);
		SoundInstance*					get(int index);
		int								autoSetInFreeIndex(SoundInstance* inst);

		//instance array_end

		//effects

		std::vector<SoundEffects*>* effectVector;

		int							currentForegroundEffect;
		void						initializeEffectVector();
		void						destroyEffectVector();
		
		//effects_end

		//root_sound_node

		std::vector<RootSoundNode*>*	rootSoundNodeVector;
		
		void							initializeRootSoundNodeVector();
		void							destroyRootSoundNodeVector();

		bool							updateRootSoundNode(RootSoundNode* rootnode,Ogre::Plane player_plane,Ogre::Vector3 player_velocity,bool player_ss,unsigned long millis);
		//root_sound_node_end

public:

	static OgreApplication*			ogre_app;
	static OgreInitializeSettings*	ogre_init_setts;


	//methods------------------------------------------------------------------------------------------------------

	//FMOD
	
private:

	void				initNull();
	void				loadStandardResources();


	//FMOD

	void				initFMOD();
	void				destroyFMOD();

	static				FMOD_RESULT F_CALLBACK  fmodFileOpenCallback(const char *fileName, int unicode, unsigned int *filesize, void **handle, void **userdata);
	static				FMOD_RESULT F_CALLBACK  fmodFileCloseCallback(void *handle, void *userdata);
	static				FMOD_RESULT F_CALLBACK  fmodFileReadCallback(void *handle, void *buffer, unsigned int sizebytes, unsigned int *bytesread, void *userdata);
	static				FMOD_RESULT F_CALLBACK  fmodFileSeekCallback(void *handle, unsigned int pos, void *userdata);
	
	FMOD::Channel       *GetSoundChannel(int channelIndex);

	void                 CreateSound(SoundInstance* sound);
	
	
	Ogre::String		getSonicBoomName(SonicBoomType type);

public:

	SoundHandler(OgreApplication* ogre);
	
	~SoundHandler();

	int	                 PlaySound(SoundInstance* sound,int index);
	void                 StopSound(int channelIndex);
	void                 StopSound(SoundInstance* sound);

	void				playSonicBoom(Ogre::Vector3 position,SonicBoomType type);

	void update(unsigned long millis);	
	

	//manual methods

	void setListenerCamera(Ogre::Camera* cam);
	void setListenerNode(Ogre::SceneNode* node);
	
	SoundInstance* createScreenSound(Ogre::String name,Ogre::String resGroupName,bool looped = false,SoundEffects* effect = NULL);
	SoundInstance* createStaticSound(Ogre::String name,Ogre::String resGroupName,Ogre::Vector3 position,bool looped = false,RootSoundDeleteCondition delcon = NO_SUBSOUND_DELETE_CONDITION,SoundEffects* effect= NULL);
	SoundInstance* createSound(Ogre::String name,Ogre::String resGroupName,Ogre::Vector3 position,Ogre::SceneNode* attached = NULL,bool looped = false,RootSoundDeleteCondition delcon= NO_SUBSOUND_DELETE_CONDITION,SoundEffects* effect = NULL);

	

				
	
	

};